﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using StockManagement.Commands;
using StockManagement.Helper;

namespace StockManagement.ViewModels
{
    public class InwardProductINViewModel:BaseViewModel
    {
        ObservableCollection<ProductViewModel> _InwardProductINCollection = new ObservableCollection<ProductViewModel>();
        string _consumer;
        ProductViewModel _productVM;
        DelegateCommand _updateCommand;
        DelegateCommand _discardCommand;        
        public event ProductUpdatedDelegate OnInwardProductINUpdated;
        

        public InwardProductINViewModel(ObservableCollection<ProductViewModel> allProductCollection)
        {
            PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(InwardProductViewModel_PropertyChanged);
            allProductCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(allProductCollection_CollectionChanged);
            foreach (var item in allProductCollection)
            {
                if (item.ProductType != Helper.EnumMaterialType.Manufacturing || item.ProductStatus != Helper.ProductStatus.Defined)
                    continue;

                _InwardProductINCollection.Add(item);
            }

            _updateCommand = new DelegateCommand(ExecuteUpdateProductCommand, CanExecuteCommand);
            _discardCommand = new DelegateCommand(ExecuteDiscardCommand, CanExecuteCommand);

            SelectedProduct = _InwardProductINCollection.FirstOrDefault();
        }

        void InwardProductViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "SelectedProduct":
                    InitializeProperties();
                    break;
                default:
                    break;
            }
            RaiseCommands();
        }

        void allProductCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    if (e.NewItems.Count < 1)
                        return;

                    var prod = e.NewItems[0] as ProductViewModel;
                    if (prod == null)
                        return;

                    if (prod.ProductStatus != Helper.ProductStatus.Defined)
                        return;

                    var prodm = _InwardProductINCollection.FirstOrDefault(p => p.ProductID == prod.ProductID);
                    if (prodm != null)
                        return;
                    InwardProductCollection.Add(prod);
                    if (SelectedProduct == null)
                        SelectedProduct = InwardProductCollection.FirstOrDefault();
                    break;
            }
            RaiseCommands();
        }

        private void RaiseCommands()
        {

            DiscardCommand.RaiseCanExecuteChanged();
            UpdateCommand.RaiseCanExecuteChanged();
        }

        private void InitializeProperties()
        {
            if (_productVM == null)
                return;

            InwardProdConsumer = _productVM.Consumer;
        }

        public ProductViewModel SelectedProduct
        {
            get
            {
                return _productVM;
            }
            set
            {
                _productVM = value;
                OnPropertyChanged("SelectedProduct");
            }
        }

        public string InwardProdConsumer
        {
            get { return _consumer == null ? string.Empty : _consumer; }
            set
            {
                _consumer = value;
                OnPropertyChanged("InwardProdConsumer");
            }
        }

        public DateTime Date
        {
            get { return DateTime.Now; }
        }

        public ObservableCollection<ProductViewModel> InwardProductCollection
        {
            get
            {
                return _InwardProductINCollection;
            }
        }

        public DelegateCommand UpdateCommand
        {
            get
            {
                return _updateCommand;
            }
        }

        public DelegateCommand DiscardCommand
        {
            get { return _discardCommand; }
        }

        private bool CanExecuteCommand(object parameter)
        {
            return (_productVM != null && !string.IsNullOrEmpty(InwardProdConsumer.Trim()));
        }

        private void ExecuteUpdateProductCommand(object parameter)
        {
            string strmessage = string.Format("Do you want to consume the product '{0}'?", SelectedProduct.ProductName);
            var result = ShowConfirmationMessageBox(strmessage, "Consume Product");
            if (!result)
                return;

            if (!_productVM.UpdateProduct(UpdateType.Consume,consumer: InwardProdConsumer))
                return;

            if ((OnInwardProductINUpdated != null) &&
                OnInwardProductINUpdated(_productVM))
                InwardProductCollection.Remove(_productVM);
        }

        internal bool UpdateProductProperties(ProductViewModel product, List<MaterialViewModel> materialcoll)
        {
            product.ProductStatus = Helper.ProductStatus.Inward_InProgress;
            product.Consumer = InwardProdConsumer;
            product.Date = Date;

            var bUpdated = UpdatedProduct(product,materialcoll);

            InwardProdConsumer = string.Empty;
            return bUpdated;
        }

        private void ExecuteDiscardCommand(object parameter)
        {
            var result = ShowConfirmationMessageBox("Do you want to discard the changes to new product?", "Discard");
            if (!result)
                return;

            InitializeProperties();
            RaiseCommands();
        }

        private bool UpdatedProduct(ProductViewModel product, List<MaterialViewModel> materialcoll)
        {
            //Use transaction here to update the product status and synchronize the material quantity

            //Adapter ada = new Adapter();
            //return ada.UpdateProduct(_productVM.Product);
            foreach (var item in product.MaterialsQuantity)
            {
                var material = materialcoll.Where(m => m.MaterialID == item.MaterialID).FirstOrDefault();
                material.Quantity = material.Quantity - item.MaterialQuantity;
            }
            return true;
        }
    }
}
